package com.zoweunion.mechanic.plugins.websocket;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
  
/** 
 * WebSocket服务端示例 
 */  
@Component
//访问服务端的url地址
@ServerEndpoint(value = "/websocket/{id}")
public class WebSocketServer {
  private static int onlineCount = 0;
  private static ConcurrentHashMap<String, WebSocketServer> webSocketSet = new ConcurrentHashMap<>();

  //与某个客户端的连接会话，需要通过它来给客户端发送数据
  private Session session;
  private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
  private String id = "";
  
  
  /**
   * 连接建立成功调用的方法*/
  @OnOpen
  public void onOpen(@PathParam(value = "id") String id, Session session) {
      this.session = session;
      this.id = id;//接收到发送消息的人员编号
      webSocketSet.put(id, this);     //加入set中
      addOnlineCount();           //在线数加1
      log.info("用户"+id+"加入！当前在线人数为" + getOnlineCount());
      try {
          sendMessage("连接成功");
      } catch (IOException e) {
          log.error("websocket IO异常");
      }
  }

  /**
   * 连接关闭调用的方法
   */
  @OnClose
  public void onClose() {
      webSocketSet.remove(this.id);  //从set中删除
      subOnlineCount();           //在线数减1
      log.info("有一连接关闭！当前在线人数为" + getOnlineCount());
  }

  /**
   * 收到客户端消息后调用的方法
   *
   * @param message 客户端发送过来的消息*/
  @OnMessage
  public void onMessage(String message, Session session) {
      System.out.println("来自客户端的消息:" + message);
  }

  /**
   *
   * @param session
   * @param error
   */
  @OnError
  public void onError(Session session, Throwable error) {
      log.error("发生错误");
      error.printStackTrace();
  }

  /**
   * 发送消息的具体方法
   * @param message
   * @throws IOException
   */
  public void sendMessage(String message) throws IOException {
      this.session.getBasicRemote().sendText(message);
  }

  /**
   * 发送信息给指定ID用户，如果用户不在线则返回不在线信息给自己
   * @param message
   * @param sendUserId
   * @throws IOException
   */
  public void sendtoUser(String message,String sendUserId){
      try {
          if (webSocketSet.get(sendUserId) != null) {
                  webSocketSet.get(sendUserId).sendMessage(message);
          } else {
              log.info("当前用户不在线："+sendUserId);
          }
      } catch (IOException e) {
          log.info("发送信息失败："+sendUserId,e.getMessage());
      }
  }

  /**
   * 发送信息给所有人
   * @param message
   * @throws IOException
   */
  public void sendtoAll(String message) throws IOException {
      for (String key : webSocketSet.keySet()) {
          try {
              webSocketSet.get(key).sendMessage(message);
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }


  public static synchronized int getOnlineCount() {
      return onlineCount;
  }

  public static synchronized void addOnlineCount() {
      WebSocketServer.onlineCount++;
  }

  public static synchronized void subOnlineCount() {
      WebSocketServer.onlineCount--;
  }
}

